#include "BackgroundDirectDraw.h"

namespace YoghurtGum
{

	BackgroundDirectDraw::BackgroundDirectDraw() : Background()
	{
		m_TargetSurface = RenderMethodDirectDraw::GetSingleton()->GetBackBuffer();
		m_TargetObject = RenderMethodDirectDraw::GetSingleton()->GetObject();
	}

	BackgroundDirectDraw::~BackgroundDirectDraw()
	{

	}

	bool BackgroundDirectDraw::Draw(int32 a_X, int32 a_Y, bool a_RepeatX /*= true*/, bool a_RepeatY /*= true*/)
	{
		LPDIRECTDRAWSURFACE target = RenderMethodDirectDraw::GetSingleton()->GetBackBuffer();

		DDSURFACEDESC desc;
		ZeroMemory(&desc, sizeof(desc));
		desc.dwSize = sizeof(desc);

		if (ErrorDirectDraw::Failed(target->Lock(
					NULL,
					&desc,
					0, 
					NULL
				)
			)
		)
		{
			ERROR_EXPLAIN("Failed to lock backbuffer surface.");
			return false;
		}

		//desc.lpSurface

		uint8* dst = (uint8*)desc.lpSurface;
		uint32 dst_pitch = desc.lPitch;
		dst += (a_Y * dst_pitch) + (a_X * m_PixelSize);

		uint8* src = m_Buffer;

		uint32 width  = (a_X + m_Width > desc.dwWidth)   ? m_Width  - (desc.dwWidth  - a_X) : m_Width;
		uint32 height = (a_Y + m_Height > desc.dwHeight) ? m_Height - (desc.dwHeight - a_Y) : m_Height;
		for (uint32 y = 0; y < height; y++)
		{
			memcpy(dst, src, width * m_PixelSize);
			dst += dst_pitch;
			src += m_Pitch;
		}

		if (ErrorDirectDraw::Failed(target->Unlock(
					NULL
				)
			)
		)
		{
			ERROR_EXPLAIN("Failed to unlock backbuffer surface.");
			return false;
		}

		return true;
	}

	bool BackgroundDirectDraw::SetData(ImageData* a_Data)
	{
		LPDIRECTDRAWSURFACE surf;

		if (ErrorDirectDraw::Failed(m_TargetObject->CreateSurface (
					&a_Data->desc,
					&surf,
					NULL
				)
			)
		)
		{
			ERROR_EXPLAIN("Failed to create temporary surface.");
			return false;
		}

		if (ErrorDirectDraw::Failed(surf->Blt(
					&a_Data->dim,
					a_Data->surf,
					NULL,
					NULL,
					NULL
				)
			)
		)
		{
			ERROR_EXPLAIN("Failed to copy data to temporary surface.");
			return false;
		}

		DDSURFACEDESC desc;
		ZeroMemory(&desc, sizeof(desc));
		desc.dwSize = sizeof(desc);

		if (ErrorDirectDraw::Failed(surf->Lock(
					NULL,
					&desc,
					0,
					NULL
				)
			)
		)
		{
			ERROR_EXPLAIN("Failed to lock temporary surface.");
			return false;
		}

		m_Width      = desc.dwWidth;
		m_Height     = desc.dwHeight;
		m_PixelSize  = desc.lXPitch;
		m_Pitch      = desc.dwWidth * desc.lXPitch;

		m_Buffer = new uint8[m_Pitch * m_Height];
		memcpy(m_Buffer, desc.lpSurface, m_Pitch * m_Height);

		if (ErrorDirectDraw::Failed(surf->Unlock(
					NULL
				)
			)
		)
		{
			ERROR_EXPLAIN("Failed to unlock temporary surface.");
			return false;
		}

		return true;
	}
}; // namespace YoghurtGum